package si.banst.sledi.ejb;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.logging.Logger;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.EJBException;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;

import si.banst.sledi.Operand;
import si.banst.sledi.Pogoj;
import si.banst.sledi.ZapisSledi;
import si.banst.sledi.ejb.napake.NapakaPriPovprasevanju;
import si.banst.sledi.ejb.napake.NapakaPriZapisu;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.Mongo;
import com.mongodb.MongoException;

/**
 * Session Bean implementation class ShrambaSlediBean
 */
@Stateless
@LocalBean
public class ShrambaSlediBean {

	private static final Logger logger = Logger
			.getLogger(ShrambaSlediBean.class.getName());
	private static final String MONGO_DB = "BanstSledi";
	private static final String MONGO_DB_USER = "banstslediuser";
	private static final String MONGO_DB_PASS = "banstsledipass";
	private static final int MONGO_DB_PORT = 27017;
	private static final String MONGO_DB_HOST = "sledidb.banst.si";

	private static Mongo mongo;
	private static DB mongoDB;

	public ShrambaSlediBean() {
		super();
	}

	@PostConstruct
	public void connect() {
		try {
			if (mongo != null || mongoDB != null) {
				logger.fine("Povezava z bazo mongo je odprta");
			} else {
				logger.fine("Povezovanje z bazo mongo.");
				mongo = new Mongo(MONGO_DB_HOST, MONGO_DB_PORT);
				mongoDB = mongo.getDB(MONGO_DB);

				if (mongoDB.authenticate(MONGO_DB_USER,
						MONGO_DB_PASS.toCharArray()) != true)
					throw new MongoException("Authentication not succesfull.");
				logger.fine("Avtentikacija uspešna.");
			}

			logger.fine("Povezava z bazo Mongo vzpostavljena in avtenticirana. ");
		} catch (Exception e) {
			logger.severe("Napaka pri povezovanju z bazo Mongo.");
			throw new EJBException("Napaka pri povezovanju z bazo Mongo.", e);
		}
	}

	@PreDestroy
	public void disconnect() {
		try {
			mongo.close();
			logger.fine("Povezava z bazo Mongo zaprta.");
		} catch (Exception e) {
			logger.severe("Napaka pri zapiranju Mongo.");
			throw new EJBException("Napaka pri zapiranju Mongo.", e);
		}
	}

	public void zapisiSled(ZapisSledi zapisSledi) throws NapakaPriZapisu {

		try {
			logger.finer("Začenjam zapis sledi.");
			DBCollection zbirka = mongoDB.getCollection(zapisSledi
					.getVrstaSledi());
			logger.finest("Zbirka odprta.");
			BasicDBObject dokument = new BasicDBObject();

			Calendar koledar = Calendar.getInstance();
			koledar.setTime(zapisSledi.getCasSledi());
			BasicDBObject casSledi = new BasicDBObject();
			dokument.put("datumCasSledi", casSledi);
			casSledi.put("datumCasSledi", zapisSledi.getCasSledi().toString());
			casSledi.put("letoSledi", koledar.get(Calendar.YEAR));
			casSledi.put("mesecSledi", koledar.get(Calendar.MONTH));
			casSledi.put("danSledi", koledar.get(Calendar.DAY_OF_MONTH));
			casSledi.put("uraSledi", koledar.get(Calendar.HOUR_OF_DAY));
			casSledi.put("minutaSledi", koledar.get(Calendar.MINUTE));
			casSledi.put("sekundaSledi", koledar.get(Calendar.SECOND));
			casSledi.put("milisekundaSledi", koledar.get(Calendar.MILLISECOND));

			for (String naziv : zapisSledi.getElementi().keySet())
				dokument.put(naziv, zapisSledi.getElementi().get(naziv));

			logger.info("Zapisujem sled: " + zapisSledi);
			zbirka.insert(dokument);

		} catch (Exception e) {
			logger.severe("Napaka pri zapisovanju sledi v Mongo." + e);
			e.printStackTrace();
			throw new NapakaPriZapisu(
					"Napaka pri zapisovanju sledi v bazo Mongo.", e);
		}

	}

	public List<String> vrniSledi(List<Pogoj> pogoji, String vrstaZbirke)
			throws NapakaPriPovprasevanju {
		BasicDBObject povprasevanje = new BasicDBObject();
		for (Pogoj pogoj : pogoji) {
			if (pogoj.getOperand() == Operand.ENAK_KOT)
				povprasevanje
						.put(pogoj.getParameter(),
								pogoj.getTipVrednosti() == Pogoj.TipVrednosti.INT ? pogoj
										.getVrednostInt() : pogoj
										.getVrednostString());
			else
				povprasevanje
						.put(pogoj.getParameter(),
								new BasicDBObject(
										pogoj.getOperand().getVrednost(),
										pogoj.getTipVrednosti() == Pogoj.TipVrednosti.INT ? pogoj
												.getVrednostInt() : pogoj
												.getVrednostString()));
		}

		logger.finer("Začenjam zapis sledi.");
		DBCollection zbirka = mongoDB.getCollection(vrstaZbirke);
		logger.finest("Zbirka odprta.");

		List<String> rezultati = new ArrayList<String>();
		DBCursor kurzor = zbirka.find(povprasevanje);
		while (kurzor.hasNext()) {
			rezultati.add(kurzor.next().toString());
		}

		return null;
	}
}
